package com.sunrise.generico.bean;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import javax.annotation.Resource;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ComponentSystemEvent;

import lombok.Getter;
import lombok.Setter;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;

import com.sunrise.generico.entidade.Usuario;
import com.sunrise.generico.entidade.iface.EntidadeManter;
import com.sunrise.generico.enums.TipoStatus;
import com.sunrise.generico.servico.ManterService;
import com.sunrise.generico.util.MessagesUtil;
import com.sunrise.generico.visao.Filtro;

@ManagedBean
@ViewScoped
@Controller
public abstract class ManterBean<E extends EntidadeManter> {

	@Getter
	@Setter
	private E entidade;

	@Getter
	@Setter
	private Filtro filtro;

	@Getter
	@Setter
	private Collection<E> entidades;

	@Resource
	@Getter
	private ManterService<E> service;

	@Getter
	@Setter
	private Collection<TipoStatus> status;

	public void preRenderNew(ComponentSystemEvent event) {
		if (entidade == null) {
			inicializarEntidade();
		}
	}

	public void preRenderEdit(ComponentSystemEvent event) {

	}

	public Usuario obterUsuarioLogado() {
		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
		return getService().buscarUsuarioPorUsername(auth.getName());
	}

	public void preRenderList(ComponentSystemEvent event) {
		setStatus(Arrays.asList(TipoStatus.values()));
		inicializarEntidade();
		setFiltro(new Filtro());
		getFiltro().setAtivo(getStatus().iterator().next());
		buscarPorNome();
	}

	public void carregarListagem() {
		setStatus(Arrays.asList(TipoStatus.values()));
		inicializarEntidade();
		setFiltro(new Filtro());
		setEntidades(service.listarOrdenado(entidade));
	}

	public abstract List<E> iniciarlizarListEntidade();

	public abstract void inicializarEntidade();

	public void buscarPorNome() {
		setEntidades(service.buscarPorNomeSomenteAtivo(getEntidade(), getFiltro().getNome(), Boolean.TRUE));
	}

	public List<String> autoCompleteNome(String nome) {
		getFiltro().setNome(nome);
		buscarPorNome();
		List<String> listaEntidades = new ArrayList<String>();
		for (EntidadeManter e : getEntidades()) {
			listaEntidades.add(e.getNome());
		}
		return listaEntidades;
	}

	public String alterar() {
		if (service.validarCampoUnico(entidade)) {
			service.alterar(entidade);
			MessagesUtil.addNewInfoMessage(MessagesUtil.getMessageKey("alteradoSucesso"));
			return getListar();
		} else {
			MessagesUtil.addNewInfoMessage(MessagesUtil.getMessageKey("campoExistente"));
		}
		return null;
	}
	
	public String merge() {
		if (service.validarCampoUnico(entidade)) {
			service.merge(entidade);
			MessagesUtil.addNewInfoMessage(MessagesUtil.getMessageKey("alteradoSucesso"));
			return getListar();
		} else {
			MessagesUtil.addNewInfoMessage(MessagesUtil.getMessageKey("campoExistente"));
		}
		return null;
	}
	

	public String salvar() {
		try {
			if (service.validarCampoUnico(entidade)) {
				service.inserir(entidade);
				MessagesUtil.addNewInfoMessage(MessagesUtil.getMessageKey("criadoSucesso"));
				carregarListagem();
				return getListar();
			} else {
				MessagesUtil.addNewInfoMessage(MessagesUtil.getMessageKey("campoExistente"));
			}
		} catch (Exception ex) {
			MessagesUtil.addNewInfoMessage(ex.getMessage());

		}
		return null;
	}
	

	public String salvarContinuar() {
		try {
			if (service.validarCampoUnico(entidade)) {
				service.inserir(entidade);
				MessagesUtil.addNewInfoMessage(MessagesUtil.getMessageKey("criadoSucesso"));
				return criarEntidade();
			} else {
				MessagesUtil.addNewInfoMessage(MessagesUtil.getMessageKey("campoExistente"));
			}
		} catch (Exception ex) {
			MessagesUtil.addNewInfoMessage(ex.getMessage());

		}
		return null;
	}
	
	public String cancelar() {
		return getListar();
	}

	public String remover() {
		try {
			MessagesUtil.addNewInfoMessage(service.remover(entidade));
			carregarListagem();
			return getListar();
		} catch (Exception e) {
			MessagesUtil.addNewInfoMessage(MessagesUtil.getMessageKey("registroNaoExcluido"));
			return null;
		}
	}

	public String criarEntidade() {
		String entidadeSimpleName = entidade.getClass().getSimpleName();
		inicializarEntidade();
		FacesContext.getCurrentInstance().getExternalContext().getFlash().setKeepMessages(true);
		return "n" + entidadeSimpleName + ".xhtml?faces-redirect=true&amp;includeViewParams=true";
	}

	public String getListar() {
		String entidadeSimpleName = entidade.getClass().getSimpleName();
		inicializarEntidade();
		FacesContext.getCurrentInstance().getExternalContext().getFlash().setKeepMessages(true);
		return "l" + entidadeSimpleName + ".xhtml?faces-redirect=true&amp;includeViewParams=true";
	}

}
